package ar.com.globallogic.promomr.services;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import ar.com.globallogic.promomr.domain.Content;
import ar.com.globallogic.promomr.domain.Document;
import ar.com.globallogic.promomr.domain.Folder;
import ar.com.globallogic.promomr.domain.Image;
import ar.com.globallogic.promomr.domain.Video;
import ar.com.globallogic.promomr.exceptions.ContentNotFoundException;
import ar.com.globallogic.promomr.exceptions.FolderNotFoundException;
import ar.com.globallogic.promomr.persistance.ContentRepository;
import ar.com.globallogic.promomr.persistance.DocumentRepository;
import ar.com.globallogic.promomr.persistance.FolderRepository;
import ar.com.globallogic.promomr.persistance.ImageRepository;
import ar.com.globallogic.promomr.persistance.VideoRepository;

@Service
public class ContentServiceImpl implements ContentService{

	private static final Logger logger = LoggerFactory.getLogger(ContentServiceImpl.class);
	
	private ContentRepository contentRepository;
	private FolderRepository folderRepository;
	private VideoRepository videoRepository;
	private ImageRepository imageRepository;
	private DocumentRepository documentRepository;

	@Autowired
	public ContentServiceImpl(ContentRepository contentRepository, FolderRepository folderRepository, 
			VideoRepository videoRepository, ImageRepository imageRepository, DocumentRepository documentRepository) {
		super();
		this.contentRepository = contentRepository;
		this.folderRepository = folderRepository;
		this.videoRepository = videoRepository;
		this.imageRepository = imageRepository;
		this.documentRepository = documentRepository;
	}

	public Content save(Content content) {
		logger.info(String.format("Saving content with name %s.", content.getName()));
		Folder parent = folderRepository.findOne(content.getParentId());
		if(parent == null){
			logger.error(String.format("Content with name %s was not saved. Parent folder with id %s was not found.", content.getName(), content.getParentId()));
			throw new FolderNotFoundException(content.getParentId());
		}
		parent.testNameForChild(content);
		contentRepository.save(content);
		parent.addChild(content);
		folderRepository.save(parent);
		logger.info(String.format("Content with name %s was saved.", content.getName()));
		return content;
	}

	public Content update(Content content) {
		contentRepository.save(content);
		logger.info(String.format("Content with id %s was updated.", content.getId()));
		return content;
	}
	
	public Content findOne(String id) {
		logger.info(String.format("Finding content with id %s.", id));
		Content content = contentRepository.findOne(id);
		if(content == null){
			logger.error(String.format("Content with id %s was not found.", id));
			throw new ContentNotFoundException(id);
		}
		logger.info(String.format("Content with id %s was found.", id));
		return content;
	}

	@Override
	public List<String> findByProperties(String name, String description) {
		logger.info(String.format("Finding contents with name %s, description %s.", name, description));
		List<Content> contents = contentRepository.findByProperties(name, description);
		return getContentIds(contents);
	}
	
	@Override
	public List<String> findVideosByProperties(String name, String description, String format, String quality, Long durationInSecondsGreaterThanEquals, Long durationInSecondsLessThanEquals) {
		logger.info(String.format("Finding videos with name %s, description %s, format %s, quality %s, duration-gte %s, duration-lte %s.", name, description, format, quality, durationInSecondsGreaterThanEquals, durationInSecondsLessThanEquals));
		List<Video> videos = videoRepository.findByProperties(name, description, format, quality, durationInSecondsGreaterThanEquals, durationInSecondsLessThanEquals);
		return getContentIds(videos);
	}
	
	@Override
	public List<String> findImagesByProperties(String name, String description, List<String> labels) {
		logger.info(String.format("Finding images with name %s, description %s, labels %s.", name, description, labels));
		labels = (labels == null) ? new ArrayList<String>() : labels;
		List<Image> images = imageRepository.findByProperties(name, description, labels);
		return getContentIds(images);
	}
	
	@Override
	public List<String> findDocumentsByProperties(String name, String description, String title, String author, Long amountOfPagesGreaterThanEquals, Long amountOfPagesLessThanEquals) {
		logger.info(String.format("Finding documents with name %s, description %s, title %s, author %s, pages-gte %s, pages-lte %s.", name, description, title, author, amountOfPagesGreaterThanEquals, amountOfPagesLessThanEquals));
		List<Document> documents = documentRepository.findByProperties(name, description, title, author, amountOfPagesGreaterThanEquals, amountOfPagesLessThanEquals);
		return getContentIds(documents);
	}
	
	private List<String> getContentIds(List<? extends Content> contents){
		List<String> ids = new ArrayList<String>();
		for (Content content : contents) {
			ids.add(content.getId());
		}
		return ids;		
	}

}
